package cn.stylefeng.guns.sys.modular.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.core.properties.TaskConfig;
import cn.stylefeng.guns.sys.core.util.DingdingUtil;
import cn.stylefeng.guns.sys.core.util.ExcelFormatUtil;
import cn.stylefeng.guns.sys.modular.system.controller.BaseFrontController;
import cn.stylefeng.guns.sys.modular.system.entity.Dept;
import cn.stylefeng.guns.sys.modular.system.entity.DingdingDayAttend;
import cn.stylefeng.guns.sys.modular.system.mapper.DingdingDayAttendMapper;
import cn.stylefeng.guns.sys.modular.system.model.params.*;
import cn.stylefeng.guns.sys.modular.system.model.result.*;
import  cn.stylefeng.guns.sys.modular.system.service.DingdingDayAttendService;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 钉钉，前三十天，人员出勤数据 服务实现类
 * </p>
 *
 * @author zxd
 * @since 2022-03-08
 */
@Service
public class DingdingDayAttendServiceImpl extends ServiceImpl<DingdingDayAttendMapper, DingdingDayAttend> implements DingdingDayAttendService {


    private Logger logger = LoggerFactory.getLogger(DingdingDayAttendServiceImpl.class);

    @Resource
    private TaskConfig taskConfig;

    @Resource
    private DingdingDayAttendMapper dingdingDayAttendMapper;

    @Resource
    private DingdingUtil dingdingUtil;


    @Override
    public void add(DingdingDayAttendParam param){
        DingdingDayAttend entity = getEntity(param);
        this.save(entity);
    }

    @Override
    public void delete(DingdingDayAttendParam param){
        this.removeById(getKey(param));
    }

    @Override
    public void update(DingdingDayAttendParam param){
        DingdingDayAttend oldEntity = getOldEntity(param);
        DingdingDayAttend newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public DingdingDayAttendResult findBySpec(DingdingDayAttendParam param){
        return null;
    }

    @Override
    public List<DingdingDayAttendResult> findListBySpec(DingdingDayAttendParam param){
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(DingdingDayAttendParam param){
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }
    /**
     * 获取钉钉人员，部门，打卡，关联关系表
     *
     * @author wjk
     * @Date 2022-03-11
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LayuiPageInfo empAndDeptAndDingdingAttendList(EmpAndDeptAndDingdingAttendParam empAndDeptAndDingdingAttendParam) {

        Page<DingdingDayAttendResult> pageContext = getPageContext();

        //判断，若传过来的参数，为空，则创一个
        if(ToolUtil.isEmpty(empAndDeptAndDingdingAttendParam)){
            empAndDeptAndDingdingAttendParam = new EmpAndDeptAndDingdingAttendParam();
        }


        //判断，若传过来的参数，查询类型为空，则默认查询2，以人事架构为查询条件；
        if(ToolUtil.isEmpty(empAndDeptAndDingdingAttendParam.getQueryType())){
            empAndDeptAndDingdingAttendParam.setQueryType(2);
        }

        //判断，若查询条件中，查询类型为按照钉钉的部门查询，则查询部门的四级参数中，最后一级的参数不为空的数据；，传到列表中查询
        if(empAndDeptAndDingdingAttendParam.getQueryType() == 1){
            //判断，若传过来的参数，最终查询id没有，则设置最终查询id，为最后一个
            if(ToolUtil.isEmpty(empAndDeptAndDingdingAttendParam.getLevelEndId())){
                //若一级有，则设置一级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelOneId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelOneId());
                }
                //若二级有，则设置二级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelTwoId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelTwoId());
                }
                //若三级有，则设置三级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelThreeId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelThreeId());
                }
                //若四级有，则设置四级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelFourId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelFourId());
                }
            }

        }
        List<DingdingEmpDeptResult>  listEmpDept = new ArrayList<DingdingEmpDeptResult>();
        //查询部门列表
        if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelEndId())){
            listEmpDept = this.baseMapper.getListEmpDept(empAndDeptAndDingdingAttendParam);
        }

        //人员未分组
        IPage page = this.baseMapper.empAndDeptAndDingdingAttendSimpleList(pageContext,empAndDeptAndDingdingAttendParam,listEmpDept);
        return LayuiPageFactory.createPageInfo(page);
    }


    /**
     *  导出excel表格
     *  获取钉钉人员，部门，打卡，关联关系表
     * @author wjk
     * @Date 2021-03-21
     */
    @Override
    public ResponseEntity<byte[]> exportEmpAndDeptAndDingdingAttendList(HttpServletRequest request, HttpServletResponse response, EmpAndDeptAndDingdingAttendParam empAndDeptAndDingdingAttendParam) {

        //判断，若传过来的参数，为空，则创一个
        if(ToolUtil.isEmpty(empAndDeptAndDingdingAttendParam)){
            empAndDeptAndDingdingAttendParam = new EmpAndDeptAndDingdingAttendParam();
        }


        //判断，若传过来的参数，查询类型为空，则默认查询2，以人事架构为查询条件；
        if(ToolUtil.isEmpty(empAndDeptAndDingdingAttendParam.getQueryType())){
            empAndDeptAndDingdingAttendParam.setQueryType(2);
        }

        //判断，若查询条件中，查询类型为按照钉钉的部门查询，则查询部门的四级参数中，最后一级的参数不为空的数据；，传到列表中查询
        if(empAndDeptAndDingdingAttendParam.getQueryType() == 1){
            //判断，若传过来的参数，最终查询id没有，则设置最终查询id，为最后一个
            if(ToolUtil.isEmpty(empAndDeptAndDingdingAttendParam.getLevelEndId())){
                //若一级有，则设置一级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelOneId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelOneId());
                }
                //若二级有，则设置二级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelTwoId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelTwoId());
                }
                //若三级有，则设置三级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelThreeId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelThreeId());
                }
                //若四级有，则设置四级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelFourId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelFourId());
                }
            }

        }

        List<DingdingEmpDeptResult>  listEmpDept = new ArrayList<DingdingEmpDeptResult>();
        //查询部门列表
        if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelEndId())){
            listEmpDept = this.baseMapper.getListEmpDept(empAndDeptAndDingdingAttendParam);
        }

        try {
            logger.info(">>>>>>>>>>钉钉人员导出excel>>>>>>>>>>");
            BaseFrontController baseFrontController = new BaseFrontController();


            // 获取查询结果
            List<DingdingEmpSimpleResult> resultList = this.baseMapper.empAndDeptAndDingdingAttendSimpleListNotPage(empAndDeptAndDingdingAttendParam,listEmpDept);
            return baseFrontController.buildResponseEntity(exportEmp(resultList, empAndDeptAndDingdingAttendParam), "钉钉近二十天打卡数据.xls");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(">>>>>>>>>>钉钉人员导出excel 异常，原因为：" + e.getMessage());
        }
        return null;
    }


    /**
     *  导出excel表格
     *  获取钉钉人员，部门，打卡，关联关系表
     *  根据大级别的部门，获取小级别的部门，并且将小部门分组；
     * @author wjk
     * @Date 2021-03-22
     */
    @Override
    public ResponseEntity<byte[]> exportEmpAndDeptArrayList(HttpServletRequest request, HttpServletResponse response, EmpAndDeptAndDingdingAttendParam empAndDeptAndDingdingAttendParam) {
        //判断，若传过来的参数，为空，则创一个
        if(ToolUtil.isEmpty(empAndDeptAndDingdingAttendParam)){
            empAndDeptAndDingdingAttendParam = new EmpAndDeptAndDingdingAttendParam();
        }


        //判断，若传过来的参数，查询类型为空，则默认查询2，以人事架构为查询条件；
        if(ToolUtil.isEmpty(empAndDeptAndDingdingAttendParam.getQueryType())){
            empAndDeptAndDingdingAttendParam.setQueryType(2);
        }

        //判断，若查询条件中，查询类型为按照钉钉的部门查询，则查询部门的四级参数中，最后一级的参数不为空的数据；，传到列表中查询
        if(empAndDeptAndDingdingAttendParam.getQueryType() == 1){
            //判断，若传过来的参数，最终查询id没有，则设置最终查询id，为最后一个
            if(ToolUtil.isEmpty(empAndDeptAndDingdingAttendParam.getLevelEndId())){
                //若一级有，则设置一级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelOneId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelOneId());
                }
                //若二级有，则设置二级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelTwoId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelTwoId());
                }
                //若三级有，则设置三级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelThreeId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelThreeId());
                }
                //若四级有，则设置四级
                if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelFourId())){
                    empAndDeptAndDingdingAttendParam.setLevelEndId(empAndDeptAndDingdingAttendParam.getLevelFourId());
                }
            }
        }
        List<DingdingEmpDeptResult>  listEmpDept = new ArrayList<DingdingEmpDeptResult>();
        //查询部门列表
        if(ToolUtil.isNotEmpty(empAndDeptAndDingdingAttendParam.getLevelEndId())){
            listEmpDept = this.baseMapper.getListEmpDept(empAndDeptAndDingdingAttendParam);
        }
        try {
            logger.info(">>>>>>>>>>钉钉人员导出excel>>>>>>>>>>");
            BaseFrontController baseFrontController = new BaseFrontController();
            // 获取查询结果
            List<DingdingEmpSimpleResult> resultList = this.baseMapper.exportEmpAndDeptArrayList(empAndDeptAndDingdingAttendParam,listEmpDept);
            return baseFrontController.buildResponseEntity(exportEmp(resultList, empAndDeptAndDingdingAttendParam), "钉钉近二十天打卡数据.xls");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(">>>>>>>>>>钉钉人员导出excel 异常，原因为：" + e.getMessage());
        }
        return null;
    }


















    private InputStream exportEmp(List<DingdingEmpSimpleResult> list, EmpAndDeptAndDingdingAttendParam empAndDeptAndDingdingAttendParam) {
        logger.info(">>>>>>>>>>>>>>>>>>>>开始进入导出方法>>>>>>>>>>");
        ByteArrayOutputStream output = null;
        InputStream inputStream1 = null;
        // 保留1000条数据在内存中
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        SXSSFSheet sheet = wb.createSheet();
        // 设置报表头样式cell样式
        CellStyle header = ExcelFormatUtil.headSytle(wb);
        // 报表体样式
        CellStyle content = ExcelFormatUtil.contentStyle(wb);
        // 每一列字段名
        String[] titles = new String[]{
                "序号",
                "钉钉部门",
                "门店",
                "营运经理",
                "督导",
                "员工姓名",
                "员工id",
                "考勤天数",
                "请假次数"};
        // 字段名所在表格的宽度，数量应与列字段名数量一致
        int[] ints = new int[]{5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000};

        // 设置总标题内容，没有可略过

        // 设置内容标题
        //内容的标题所在行
        int concentitleStartRow = 1;
        //设置表头样式
        ExcelFormatUtil.initContentTitleEX(sheet, header, concentitleStartRow, titles, ints);
        logger.info(">>>>>>>>>>>>>>>>>>>>表头样式设置完成>>>>>>>>>>");
        // 从第contentStartRow行开始为内容数据
        int contentStartRow = concentitleStartRow + 1;
        if (list != null && list.size() > 0) {
            int hangInx = 1;
            logger.info(">>>>>>>>>>>>>>>>>>>>开始遍历数据组装单元格内容>>>>>>>>>>");
            for (int i = 0; i < list.size(); i++) {
                DingdingEmpSimpleResult result = list.get(i);
                SXSSFRow row = sheet.createRow(contentStartRow + i - 1);
                int j = 0;
                // 1.序号
                SXSSFCell cell = row.createCell(j++);
                ExcelFormatUtil.setCellVal(hangInx, content, cell);
                //2.钉钉部门
                cell = row.createCell(j++);
                ExcelFormatUtil.setCellVal(result.getFullName(), content, cell);
                //3.门店
                cell = row.createCell(j++);
                ExcelFormatUtil.setCellVal(result.getDm(), content, cell);
                //4.营运经理
                cell = row.createCell(j++);
                ExcelFormatUtil.setCellVal(result.getYyjl(), content, cell);
                //5.督导
                cell = row.createCell(j++);
                ExcelFormatUtil.setCellVal(result.getDd(), content, cell);
                //6.员工姓名
                cell = row.createCell(j++);
                ExcelFormatUtil.setCellVal(result.getXm(), content, cell);

                //7.员工id
                cell = row.createCell(j++);
                ExcelFormatUtil.setCellVal(result.getBh(), content, cell);

                //8.考勤天数
                cell = row.createCell(j++);
                ExcelFormatUtil.setCellVal(result.getAttendDay(), content, cell);

                //9.请假次数
                cell = row.createCell(j++);
                ExcelFormatUtil.setCellVal(result.getRequestDay(), content, cell);

                hangInx = hangInx + 1;
            }
            logger.info(">>>>>>>>>>>>>>>>>>>>结束遍历数据组装单元格内容>>>>>>>>>>");
        }
        try {
            output = new ByteArrayOutputStream();
            wb.write(output);
            inputStream1 = new ByteArrayInputStream(output.toByteArray());
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (output != null) {
                    output.close();
                    if (inputStream1 != null) {
                        inputStream1.close();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return inputStream1;


    }


    /**
     * 根据钉钉编号，查询近二十天，关联的表单信息
     *
     * @param empAndDeptAndDingdingAttendParam
     * @author wjk
     * @Date 2022-03-18
     */
    @Override
    public List<DingdingEmpSimpleResult> queryRequestDetailByBh(EmpAndDeptAndDingdingAttendParam empAndDeptAndDingdingAttendParam) {
         return this.baseMapper.queryRequestDetailByBh(empAndDeptAndDingdingAttendParam);
    }

    /**
     * 删除钉钉人员数据，根据人员在部门钉钉里面的编号
     * 并且将人员标记为离职状态
     * 将该人员的打卡记录标记为不打卡
     *
     * @author wjk
     * @Date 2022-03-16
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map deleteDingdingEmpByBhList(List<String> list) {

        Map<String,String> map = new HashMap();

        List<DingdingEmpSimpleResult> dingdingEmpSimpleResultList= this.baseMapper.empAndDeptAndDingdingAttendSimpleListByByBhList(list);
        if(dingdingEmpSimpleResultList.size()>0){
            map.put("flag","false");
            map.put("msg","删除人员中，有人员，近20天内有打卡记录，或者有请假记录,不允许删除人员数据。人员:"
                    +dingdingEmpSimpleResultList.get(0).getXm()+",打卡:"+dingdingEmpSimpleResultList.get(0).getAttendDay()+"天，关联请假单:"+dingdingEmpSimpleResultList.get(0).getRequestDay());
            return map;
        }

        //正式环境才允许操作
        if ("y".equals(taskConfig.getRun())) {
            logger.info("正式环境，允许删除钉钉内的人员数据："+list.toString());

            //将人员设置为离职状态
            Integer sizeUpdateEmpDeparture = this.baseMapper.updateEmpDepartureByBhList(list);
            map.put("empSize",String.valueOf(sizeUpdateEmpDeparture));
            // 将该人员的打卡记录标记为不打卡
            Integer sizeUpdateEmpAttendDeparture = this.baseMapper.updateEmpAttendDepartureByBhList(list);
            map.put("empSize",String.valueOf(sizeUpdateEmpAttendDeparture));

            // 删除钉钉人员数据，根据人员在部门钉钉里面的编号
            Map<String,Object> dingdingMap = dingdingUtil.deleteEmps(list);

//            if(dingdingMap.get("code").equals("0")){
//
//            }
//            List<String> listNot = new ArrayList<String>();
//            if(dingdingMap.get("code").equals("1")){
//
//                logger.info("正式环境，未成功删除的数据："+dingdingMap.get("data").toString());
//                listNot = (List<String>)dingdingMap.get("data");
//
//                HashSet hs1 = new HashSet(list);
//                HashSet hs2 = new HashSet(listNot);
//                hs1.removeAll(hs2);
//                List<String> listNew =new ArrayList<String>();
//                listNew.addAll(hs1);
//                list = listNew;
//
//            }

//            //将人员设置为离职状态
//            Integer sizeUpdateEmpDeparture = this.baseMapper.updateEmpDepartureByBhList(list);
//            map.put("empSize",String.valueOf(sizeUpdateEmpDeparture));
//            // 将该人员的打卡记录标记为不打卡
//            Integer sizeUpdateEmpAttendDeparture = this.baseMapper.updateEmpAttendDepartureByBhList(list);
//            map.put("empSize",String.valueOf(sizeUpdateEmpAttendDeparture));

//            if(listNot.size()>0){
//                map.put("flag","false");
//                map.put("msg","未成功删除数据["+listNot.toString()+"],请确认,人员是否已经被删除");
//                return map;
//            }

            if(sizeUpdateEmpDeparture>0){
                map.put("flag","true");
                return map;
            }
        }

        //测试环境才允许操作
        if ("n".equals(taskConfig.getRun())) {
//            //将人员设置为离职状态
//            Integer sizeUpdateEmpDeparture = this.baseMapper.updateEmpDepartureByBhList(list);
//            map.put("empSize",String.valueOf(sizeUpdateEmpDeparture));
//            // 将该人员的打卡记录标记为不打卡
//            Integer sizeUpdateEmpAttendDeparture = this.baseMapper.updateEmpAttendDepartureByBhList(list);
//            map.put("empSize",String.valueOf(sizeUpdateEmpAttendDeparture));


            logger.info("测试环境，模拟删除了钉钉内的人员数据："+list.toString());
            List<String> listTest = new ArrayList<String>();
            listTest.add("AAAAAABBBBBBBBBB");
            Map<String,Object> dingdingMap = dingdingUtil.deleteEmps(listTest);
            logger.info("测试环境，模拟删除了钉钉内的人员数据------结果："+dingdingMap.toString());

            map.put("flag","false");
            map.put("msg","模拟测试删除人成功。");
            return map;
        }

        map.put("flag","false");
        map.put("msg","权限不正确，请确认，当前登录人是否有操作权限，当前有操作权限仅限人事部。");
        return map;
    }

    //原始不分页列表，数据不分页，报错，链接关闭，原因，是内存溢出
//        List<DingdingEmpResult> list = this.baseMapper.empAndDeptAndDingdingAttendList();

    // 分页列表，分页不正确，
//        Page<DingdingDayAttendResult> pageContext = getPageContext();
//        IPage page = this.baseMapper.empAndDeptAndDingdingAttendListPage(pageContext);
//        page.getRecords();

    // 分页列表，分页正确，
//        Page<DingdingDayAttendResult> pageContext = getPageContext();
//        IPage page = this.baseMapper.empAndDeptAndDingdingAttendListPageMaster(pageContext);
//        page.getRecords();



    @Override
    public List<Dept> queryDepts(Pid pid) {
        return this.baseMapper.queryDepts(pid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LayuiPageInfo findPageYyjl(BtyPerformanceMonthInformationParam param) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageListYyjl(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public LayuiPageInfo findPageDd(AttendAuditBtyAreaParam param) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageListDd(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public LayuiPageInfo findPageDm(AttendAuditBtyAreaParam param) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageListDm(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public LayuiPageInfo findPageXm() {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageListXm(pageContext);
        return LayuiPageFactory.createPageInfo(page);
    }


    private Serializable getKey(DingdingDayAttendParam param){
        return param.getId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private DingdingDayAttend getOldEntity(DingdingDayAttendParam param) {
        return this.getById(getKey(param));
    }

    private DingdingDayAttend getEntity(DingdingDayAttendParam param) {
        DingdingDayAttend entity = new DingdingDayAttend();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

    @Override
    public void batchInsert(List list) {
        dingdingDayAttendMapper.batchInsert(list);
    }
}
